/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */

package info.peigen.hotpot.component.gateway.dianlan.protocol;

import cn.hutool.core.bean.BeanUtil;
import info.peigen.hotpot.component.gateway.core.util.HexUtil;
import info.peigen.hotpot.component.gateway.dianlan.annotations.DianlanProtocol;
import info.peigen.hotpot.component.gateway.dianlan.facade.enums.DianlanEncryptType;
import info.peigen.hotpot.component.gateway.dianlan.facade.enums.DianlanFrameSign;
import info.peigen.hotpot.component.gateway.dianlan.util.CrcUtil;
import lombok.*;
import lombok.experimental.Accessors;
import lombok.experimental.FieldDefaults;
import lombok.experimental.SuperBuilder;

import static info.peigen.hotpot.component.gateway.dianlan.annotations.DianlanProtocol.DianlanProtocolDataType.*;

/**
 * <b>(Dianlan)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2022/8/11
 */
@SuperBuilder
@Data
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PUBLIC)
@Accessors(chain = true)
public class Dianlan {
    /** 固定 */
    @Builder.Default
    @DianlanProtocol(length = 1, start = 0, end = 1, dataType = BIN)
    String             startSign     = "68";
    /** 长度 */
    @DianlanProtocol(length = 1, start = 1, end = 2, dataType = INT)
    String             length;
    /** 序列号 */
    @DianlanProtocol(length = 2, start = 2, end = 3, dataType = BIN)
    String             serialNumber;
    /** 加密标志 */
    @Builder.Default
    @DianlanProtocol(length = 1, start = 4, end = 5, dataType = ENUM)
    DianlanEncryptType encryptedSign = DianlanEncryptType.None;
    /** 帧类型标志 */
    @DianlanProtocol(length = 1, start = 5, end = 6, dataType = ENUM)
    DianlanFrameSign   frameSign;
    /** 数据 */
    @DianlanProtocol(start = 6, end = -2, dataType = DATA)
    String             data;
    /** 帧校验域 */
    @DianlanProtocol(length = 2, start = -2, end = -1, dataType = END)
    String             frameCheck;

    public String check() {
        DianlanFrameCheck frameCheck = DianlanFrameCheck.builder().build();
        BeanUtil.copyProperties(this, frameCheck);
        String resourceData = HexUtil.binaryToHex(frameCheck.getData());
        String data = frameCheck.getSerialNumber() + frameCheck.getEncryptedSign().code() +
                frameCheck.frameSign.getCode() + resourceData;
        String str = CrcUtil.getCrc(data).replace(" ", "");
        return str;
    }

    public String dataLength() {
        int length = this.getSerialNumber().length()
                + this.getEncryptedSign().getCode().length()
                + this.getFrameSign().getCode().length()
                + this.getData().length();
        String hexLength = CrcUtil.intToHex(length / 2);
        if (hexLength.length() == 1) {
            hexLength = "0" + hexLength;
        }
        return hexLength;
    }
}